import type Stomp from "stompjs"

const handlers: Array<{
  url: string | ((...args: any[]) => string);
  callback: (...args: any[]) => any;
  headers?: {};
}> = [
    {
      url: (payload: { token: string; }) => `/user/${payload.token}/applyFriendLists`,
      callback: async (res: Stomp.Message) => {
        const body: Map<string, {
          userInfo: Omit<User, 'remark' | 'userId'>;
          otherProto: {
            applyLan: string;
            isLoading: boolean;
            isLoadingRefuse: boolean;
            time: number;
          };
        }> = new Map(JSON.parse(res.body));
        const { useUserPinia } = await import('@/pinia/user');
        const userStore = useUserPinia();
        for (const [key, value] of body.entries())
          userStore.applicationList.set(key, value);
      },
    },
    {
      url: (payload: { token: string; }) => `/user/${payload.token}/messagesList`,
      callback: async (res: Stomp.Message) => {
        const { useMessagePinia } = await import('@/pinia/messages');
        const { useUserPinia } = await import('@/pinia/user');
        const userStore = useUserPinia();
        const messageStore = useMessagePinia();
        const body: Map<string, LatestMessInfo> = new Map(JSON.parse(res.body));
        if (body.size === 1) {
          const key_: string = [...body][0][0];
          const value_: LatestMessInfo = [...body][0][1];
          const chatDatas = messageStore.chatList.get(key_);
          if (chatDatas) chatDatas.LatestMessInfo = value_;
          else {
            const chatList = [...messageStore.chatList];
            const index: number = chatList.findIndex(item => !item[1].LatestMessInfo.isTopping);
            if (value_.isTopping) {
              const topDatas = chatList.slice(0, index);
              const index_: number = topDatas.findIndex(item => value_.time > item[1].LatestMessInfo.time);
              chatList.splice(index_ >= 0 ? index_ : index, 0, [key_, {
                LatestMessInfo: value_,
                messagesDatas: new Map(),
                isRequMessRecord: false,
                isNodisplayLoading: false,
                isToppingLoading: false,
              }]);
            } else {
              const otherDatas = chatList.slice(index);
              const index_: number = otherDatas.findIndex(item => value_.time > item[1].LatestMessInfo.time);
              chatList.splice(index + (index_ >= 0 ? index_ : chatList.length - index), 0, [key_, {
                LatestMessInfo: value_,
                messagesDatas: new Map(),
                isRequMessRecord: false,
                isNodisplayLoading: false,
                isToppingLoading: false,
              }]);
            }
            messageStore.chatList = new Map(chatList);
          }
        }
        else
          for (const [key, value] of body.entries()) {
            const chatDatas = messageStore.chatList.get(key);
            if (chatDatas) chatDatas.LatestMessInfo = value;
            else messageStore.chatList.set(key, {
              LatestMessInfo: value,
              messagesDatas: new Map(),
              isRequMessRecord: false,
              isNodisplayLoading: false,
              isToppingLoading: false,
            })
            userStore.applicationList.delete(key);
          }
        if (!messageStore.isRequChatLisFinsh) messageStore.isRequChatLisFinsh = true;
      },
    },
    {
      url: (payload: { token: string; }) => `/user/${payload.token}/messages`,
      callback: async (res: Stomp.Message) => {
        const { useMessagePinia } = await import('@/pinia/messages');
        const messageStore = useMessagePinia();
        const body: {
          chatterId: string;
          id?: string; // 该id是前端生成的messageId
          value: Array<{
            messageId: string;
            content: Message;
            isHavRead: boolean;
          }>;
        } = JSON.parse(res.body);
        const chatDatas = messageStore.chatList.get(body.chatterId);
        if (chatDatas) {
          // 删除前端生成的消息
          body?.id && chatDatas.messagesDatas.delete(body.id);
          const len: number = body.value.length;
          for (let i: number = 0; i < len; i++) {
            Object.assign(body.value[i].content, { isLoading: false });
            const { messageId, content, isHavRead } = body.value[i];
            // 如果用户已经请求了聊天记录
            chatDatas.isRequMessRecord &&
              !chatDatas.messagesDatas.has(messageId) &&
              chatDatas.messagesDatas.set(
                messageId,
                content,
              )
            if (i === len - 1) {
              const time: number = chatDatas.LatestMessInfo.time;
              Object.assign(chatDatas.LatestMessInfo, {
                latestMess: content.message,
                messageId: messageId,
                time: content.time,
                type: content.type,
              });
              // 最新消息和上一条消息时间差大于一小时且该聊天没有置顶
              if (content.time! - time > 600000 && !chatDatas.LatestMessInfo.isTopping) {
                messageStore.chatList.delete(body.chatterId);
                const chatList = Array.from(messageStore.chatList);
                const index: number = chatList.findIndex(item => !item[1].LatestMessInfo.isTopping);
                chatList.splice(index, 0, [body.chatterId, chatDatas]);
                messageStore.chatList = new Map(chatList);
              }
            }
            if (!isHavRead) chatDatas.LatestMessInfo.unReadMessCou++;
          }
        } else {

        }
      },
    },
    {
      url: (payload: { token: string; }) => `/user/${payload.token}/withdrawMessage`,
      callback: async (res: Stomp.Message) => {
        const { useMessagePinia } = await import('@/pinia/messages');
        const messageStore = useMessagePinia();
        const body: {
          chatterId: string;
          messageId: string;
          latestMessId: string;
        } = JSON.parse(res.body);
        const chatDatas = messageStore.chatList.get(body.chatterId);
        const messagesDatas = chatDatas?.messagesDatas;
        if (messagesDatas) {
          messagesDatas.delete(body.messageId);
          const latestMess = messagesDatas.get(body.latestMessId);
          if (!body.latestMessId) {
            const time: number = messagesDatas.get(body.messageId)?.time!;
            Object.assign(chatDatas?.LatestMessInfo!, {
              time,
              messageId: '',
              latestMess: '',
              type: 'text',
            })
          }
          else if (chatDatas?.LatestMessInfo.messageId !== body.latestMessId)
            Object.assign(chatDatas?.LatestMessInfo!, {
              time: latestMess?.time,
              messageId: body.latestMessId,
              latestMess: latestMess?.message,
              type: latestMess?.type,
            })
        }
      },
    },
    // 告诉我是否有人同意了我的好友申请
    {
      url: (payload: { token: string; }) => `/user/${payload.token}/agreeApply`,
      callback: async (res: Stomp.Message) => {
        const body: {
          userId: string;
          userInfo: Pick<
            OtherIdInfo,
            | "avatar"
            | "nickName"
            | "remark"
            | "disabledOtherLook"
            | "disabledSelfLook"
            | "group"
          >;
          initials: string;
        } = JSON.parse(res.body);
        const { useFriendPinia } = await import('@/pinia/friend');
        const friendStore = useFriendPinia();
        if (friendStore.isRequGetAllFriend) {
          if (friendStore.friends.has(body.initials))
            friendStore.friends.get(body.initials)?.value.set(body.userId, {
              isSendLoading: false,
              remark: body.userInfo.remark,
              avatar: body.userInfo.avatar,
            });
          else {
            const friendsArr = Array.from(friendStore.friends);
            if (body.initials !== '~') {
              const index: number = friendsArr.findIndex(item => item[0] > body.initials);
              friendsArr.splice(index, 0, [body.initials, {
                value: new Map().set(body.userId, {
                  isSendLoading: false,
                  remark: body.userInfo.remark,
                  avatar: body.userInfo.avatar,
                })
              }]);
            } else friendsArr.push([body.initials, {
              value: new Map().set(body.userId, {
                isSendLoading: false,
                remark: body.userInfo.remark,
                avatar: body.userInfo.avatar,
              })
            }]);
            friendStore.friends = new Map(friendsArr);
          }
        }
        if (friendStore.isRequFriendsManage)
          for (const [key, value] of friendStore.friendsManage) {
            if (key === 'all') {
              if (value.noGroups?.isRequest) value.noGroups.friends.set(body.userId, body.userInfo)
            } else if (value?.noGroups) {
              if (key === 'disabledOtherLook') {
                if (body.userInfo.disabledOtherLook) {
                  value.noGroups.count!++;
                  value.noGroups.isRequest &&
                    value.noGroups.friends.set(body.userId, body.userInfo)
                }
              }
              else if (body.userInfo.disabledSelfLook) {
                value.noGroups.count!++;
                value.noGroups.isRequest &&
                  value.noGroups.friends.set(body.userId, body.userInfo)
              }
            } else if (value?.groups) {
              const nowGroup = body.userInfo.group ? body.userInfo.group : '无分组';
              if (value.groups?.has(nowGroup)) {
                const groupData = value.groups.get(nowGroup)!;
                groupData.count++;
                groupData?.isRequest && groupData.friends.set(body.userId, body.userInfo)
              } else value.groups?.set(nowGroup, {
                isRequest: true,
                count: 1,
                friends: new Map([[body.userId, body.userInfo]]),
              })
            }
          }
      },
    },
    // 通知自己有好友发表了动态
    {
      url: (payload: { token: string; }) => `/dynamic/${payload.token}/isHasDynamic`,
      callback: async (res: Stomp.Message) => {
        const body: {
          status: number,
        } = JSON.parse(res.body);
        const { useDynamicPinia } = await import('@/pinia/dynamic');
        const dynamicStore = useDynamicPinia();
        if (body.status === 1 && !dynamicStore.dynamicDatas.isHasNew)
          dynamicStore.dynamicDatas.isHasNew = true;
      },
    },
  ]

export default handlers